/*
Copyright DAUPHIN Maxime 2005

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
http://www.gnu.org/licenses/gpl.txt
*/
#include "Dc.h"
#include "Wnd.h"

namespace Gui {

Dc::Dc(void) 
	: m_hDC( NULL ), m_pWnd( NULL )
{
}

Dc::Dc(Wnd* pWnd) 
	: m_pWnd(pWnd)
{
	assert(m_pWnd);
	m_hDC = ::GetDC( *m_pWnd );
	assert(m_hDC);
}

Dc::Dc(HDC hDC)
	: m_hDC( hDC ), m_pWnd( NULL )
{
	assert( m_hDC );
}


Dc::~Dc(void)
{
	assert(m_hDC);
	if ( m_pWnd )
	{
		assert(m_pWnd);
		::ReleaseDC( *m_pWnd, m_hDC );
	} else {
		assert( ::DeleteDC( m_hDC ) == TRUE );
	}
}

void Dc::textOut(int x, int y, STRING str)
{
	assert(m_hDC);
	::TextOut( m_hDC, x, y, str.c_str(), (int)str.size() );
}

void Dc::fillRect( const Rect& rect, const Color &color)
{
	assert(m_hDC);
	HBRUSH hBrush = CreateSolidBrush( (COLORREF)color );
	::FillRect( m_hDC, (LPRECT)rect, hBrush );
	DeleteObject( hBrush );
}

int Dc::setBkMode( const int iBkMode )
{
	assert(m_hDC);
	return ::SetBkMode( m_hDC, iBkMode );
}

bool Dc::drawIcon( Point point, HICON hIcon )
{
	assert(m_hDC);
	assert(hIcon);
	return ( ::DrawIcon( m_hDC, point.x, point.y, hIcon ) == TRUE );
}

int Dc::drawText( const STRING string, const Rect rect, UINT uFormat )
{
	assert(m_hDC);
	return ( ::DrawText( m_hDC, string.c_str(), (int)string.size(), (LPRECT)rect, uFormat ) ); 
}

bool Dc::drawGradient( const Rect &rect, const Color &start, const Color &end)
{
	//Calc Color step
	Color step = end - start;
	
	double w = rect.getHeight();
	double stepr = step.r / w;
	double stepg = step.g / w;
	double stepb = step.b / w;
	double startr = start.r;
	double startg = start.g;
	double startb = start.b;
	
	Color _start = start;
	assert(m_hDC);
	for( int y = rect.t.y; y < rect.d.y; y++ )
	{
		Rect r = rect;
		r.t.y = y;
		r.d.y = y+1;
		Color c( iround(startr),iround(startg), iround(startb) );
		fillRect( r, c );
		startr += stepr;
		startg += stepg;
		startb += stepb;
	}
	return true;
}

Dc* Dc::createCompatibleDc()
{
	assert(m_hDC);
	return new Dc( ::CreateCompatibleDC(m_hDC) );
}

HGDIOBJ Dc::selectObject(HGDIOBJ hObject)
{
	assert(m_hDC);
	return ::SelectObject( m_hDC, hObject );
}

void Dc::bitBlt( int x, int y, int nWidth, int nHeight, Dc* pSrcDC, int xSrc, int ySrc, DWORD dwRop )
{
	assert(m_hDC);
	assert(pSrcDC);
	HDC hSrcDC = (HDC)(*pSrcDC);
	assert( ::BitBlt( m_hDC, x, y, nWidth, nHeight, hSrcDC, xSrc, ySrc, dwRop ) == TRUE );
}

void Dc::stretchBlt( const Rect &dest, const Rect &ori, Dc* pSrcDC, DWORD dwRop )
{
	assert(m_hDC);
	assert(pSrcDC);
	assert( ::StretchBlt( m_hDC, dest.t.x, dest.t.y,
		dest.getWidth(), dest.getHeight(),
		(HDC)(*pSrcDC),
		ori.t.x, ori.t.y,
		ori.getWidth(), ori.getHeight(),
		dwRop ) == TRUE );
}



PaintDc::PaintDc(Wnd *pWnd)
{
	assert(pWnd);
	m_pWnd = pWnd;
	m_hDC = ::BeginPaint( *m_pWnd, &m_ps);
	assert(m_hDC);
	
}

PaintDc::~PaintDc(void)
{
	::EndPaint( *m_pWnd, &m_ps);
}


}//End namespace Gui 
